#include <Ogre.h> 
#include <CEGUI/CEGUI.h> 

#include "include/Gui.h"
#include "include/TextureTest.h"
#include "include/Scripting.h"
#include "include/App.h"

#define SET_LIGHTMAP_PARAM_INDEX 0

using namespace Ogre;
using namespace Ei;

CEGUI::MouseButton convertOgreButtonToCegui(int buttonID)
{
    switch (buttonID)
    {
    case MouseEvent::BUTTON0_MASK:
        return CEGUI::LeftButton;
    case MouseEvent::BUTTON1_MASK:
        return CEGUI::RightButton;
    case MouseEvent::BUTTON2_MASK:
        return CEGUI::MiddleButton;
    case MouseEvent::BUTTON3_MASK:
        return CEGUI::X1Button;
    default:
        return CEGUI::LeftButton;
    }
}

///////// GUI implementation ////////////////////////////////

Gui::Gui(Ogre::SceneManager* manager, RenderWindow* window) 
{

	mGUIRenderer = new CEGUI::OgreCEGUIRenderer(window, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, manager);
        mGUISystem = new CEGUI::System(mGUIRenderer);
	
	mEventProcessor = new EventProcessor();
	mEventProcessor->initialise(window);
	mEventProcessor->startProcessingEvents();
	 
	mEventProcessor->addMouseMotionListener(this);
        mEventProcessor->addMouseListener(this);
	mEventProcessor->addKeyListener(this);
	
	mGuiEvents = new GuiEvents();	
	init();
}
Gui::~Gui()
{	
	mGUIRenderer = NULL;
	mGUISystem   = NULL;
	delete mEventProcessor;
}


/////////////// process input
void Gui::mouseMoved(MouseEvent *e)
{
        CEGUI::System::getSingleton().injectMouseMove(
                e->getRelX() * mGUIRenderer->getWidth(), 
                e->getRelY() * mGUIRenderer->getHeight());
        	
	if (mEventProcessor->getInputReader()->getMouseButton(1))
	{
	  App::sceneMgr()->getSceneNode("Camera")
		->yaw(Degree(e->getRelX() * mGUIRenderer->getWidth() * -0.2));
	  App::sceneMgr()->getSceneNode("Camera_PitchNode")
		->pitch(Degree(e->getRelY() * mGUIRenderer->getWidth() * -0.2));
	}
	
        e->consume();
}

void Gui::mouseDragged (MouseEvent *e) 
{ 
        mouseMoved(e);
}

void  Gui::mousePressed (MouseEvent *e)
{
        CEGUI::System::getSingleton().injectMouseButtonDown(
          convertOgreButtonToCegui(e->getButtonID()));
        e->consume();
}

void  Gui::mouseReleased (MouseEvent *e)
{
        CEGUI::System::getSingleton().injectMouseButtonUp(
          convertOgreButtonToCegui(e->getButtonID()));
        e->consume();
}

void  Gui::keyPressed(KeyEvent* e)
{

        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
		CEGUI::System::getSingleton().injectChar(e->getKeyChar());
        e->consume();
}

void  Gui::keyReleased(KeyEvent* e)
{
	CEGUI::System::getSingleton().injectKeyUp(e->getKey());
	e->consume();
}

void  Gui::keyClicked(KeyEvent* e) 
{
	// Do nothing
	e->consume();
}
	
////////////// frame loop
	
bool Gui::frameStarted(const FrameEvent& evt)
{
				
	//
	// set Settings of mCurrentSample
	//
	// set bar positions in MagAcc object
	float slider1, slider2,slider3,slider4; 
	slider1 = mLightmap1->getScrollPosition();
	slider2 = mLightmap2->getScrollPosition();
	slider3 = mLightmap3->getScrollPosition();
	slider4 = mFadeMesh->getScrollPosition();
	String values = "ValueSlider: 1: " + StringConverter::toString(slider1) +
				   ": 2: " + StringConverter::toString(slider2) +
				   ": 3: " + StringConverter::toString(slider3) +
				   ": 4: " + StringConverter::toString(slider4);
	
	if (mEnableGui->isSelected())
	{
		if (App::sceneMgr()->hasEntity("plane"))
		{
	 	SubEntity* pSub = App::sceneMgr()->getEntity("plane")->getSubEntity(0);
	 	pSub->setCustomParameter(SET_LIGHTMAP_PARAM_INDEX, Vector4(slider1,slider2,slider3,slider4));
		}
	
		for(int i = 0 ; App::sceneMgr()->hasEntity("pilaar" + StringConverter::toString(i)) ; i ++)
		{
		 SubEntity* pSub = App::sceneMgr()->getEntity("pilaar" + StringConverter::toString(i))->getSubEntity(0);
	 	pSub->setCustomParameter(SET_LIGHTMAP_PARAM_INDEX, Vector4(slider1,slider2,slider3,slider4));
		}
		
		for(int i = 0 ; App::sceneMgr()->hasEntity("muur" + StringConverter::toString(i)) ; i ++)
		{
		 SubEntity* pSub = App::sceneMgr()->getEntity("muur" + StringConverter::toString(i))->getSubEntity(0);
	 	pSub->setCustomParameter(SET_LIGHTMAP_PARAM_INDEX, Vector4(slider1,slider2,slider3,slider4));
		}
		
        
	
	if(slider4 >= (mFadeMesh->getDocumentSize() - 1))
 	  {
	  static_cast<MaterialPtr> (MaterialManager::getSingleton( ).getByName("PaalBlender"))
          ->getTechnique(0)->getPass(0)->setDepthWriteEnabled(true);
          
          static_cast<MaterialPtr> (MaterialManager::getSingleton( ).getByName("MuurBlender"))
          ->getTechnique(0)->getPass(0)->setDepthWriteEnabled(true);
          }
          else
          {
	  static_cast<MaterialPtr> (MaterialManager::getSingleton( ).getByName("PaalBlender"))
          ->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
	  
	  static_cast<MaterialPtr> (MaterialManager::getSingleton( ).getByName("MuurBlender"))
          ->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);	
	  }
	}
	// move camera
	float speed = App::scripting()->getTableFloat("game", "speed");
	// move camera
	 	Quaternion orient = App::sceneMgr()->getCamera("Mono camera")->getDerivedOrientation();
		// move front - back
   	
	    	Vector3 trans = Vector3(0,0,0);
	   	// move front <-> back
      		if (mEventProcessor->getInputReader()->isKeyDown(KC_W)) {                           
	      	 trans = trans + Vector3(0,0,-1  ); }  
       		if (mEventProcessor->getInputReader()->isKeyDown(KC_S) ) {                           
           	 trans = trans + Vector3(0,0,1 );  } 
             	 	
		// Left  <-> right             
        	if (mEventProcessor->getInputReader()->isKeyDown(KC_A)) {                           
           	trans = trans + Vector3(-1 , 0 ,0);}  
        	if (mEventProcessor->getInputReader()->isKeyDown(KC_D)) {                           
		trans = trans + Vector3(1 , 0 ,0);}
		
		trans =  orient * trans;
		trans.y = 0;
		
		// move Up <-> down
        	if (mEventProcessor->getInputReader()->isKeyDown(KC_E) ) {                           
           	trans = trans + Vector3(0,-1  ,0); }  
        	if (mEventProcessor->getInputReader()->isKeyDown(KC_Q)) {                           
           	trans = trans + Vector3(0,1 ,0);} 
		trans.normalise();
		trans = trans * speed;
		App::sceneMgr()->getSceneNode("Camera")->translate(trans);
		Vector3 newPosition= App::sceneMgr()->getSceneNode("Camera")->getWorldPosition();
    		String position = "Camera Position: X: " + StringConverter::toString(newPosition.x) +
				   ": Y " + StringConverter::toString(newPosition.y) +
				   ": Z " + StringConverter::toString(newPosition.z);
				   
              //  mCamPositionWindow->setText((CEGUI::utf8*)position.c_str());
 	   		
		
	return true;		
}

bool Gui::frameEnded(const FrameEvent& evt)
{
	return true;
}

void Gui::init()
{
	
        CEGUI::Logger::getSingleton().setLoggingLevel(CEGUI::Insane);
        CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLookSkin.scheme");
        mGUISystem->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
        CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseMoveCursor");
        mGUISystem->setDefaultFont((CEGUI::utf8*)"BlueHighway-12");
        
        mEditorGuiSheet = CEGUI::WindowManager::getSingleton().loadWindowLayout((CEGUI::utf8*)"VectorEditorLayout.xml");
	mGUISystem->setGUISheet(mEditorGuiSheet);

	mEditorGuiSheet->enable();
/*
	// assing functions to buttons	
  	CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"AddSpeaker")->subscribeEvent
	  (CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&GuiEvents::addSpeaker, mGuiEvents));
  	CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"RemoveSpeaker")->subscribeEvent
	  (CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&GuiEvents::removeSpeaker, mGuiEvents));
  	CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"NextSpeaker")->subscribeEvent
	  (CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&GuiEvents::nextSpeaker, mGuiEvents));
  	CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"PrevSpeaker")->subscribeEvent
	  (CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&GuiEvents::prevSpeaker, mGuiEvents)); 
	CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"GotoSelected")->subscribeEvent
	  (CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&GuiEvents::goToSelected, mGuiEvents));
  	CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"SaveSound")->subscribeEvent
	  (CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&GuiEvents::saveSoundScape, mGuiEvents));
	  
	CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"TopView")->subscribeEvent
	  (CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&GuiEvents::topView, mGuiEvents));
	
	CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"SpeakerControlsWin/NextSample")->subscribeEvent
	(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&GuiEvents::nextSample, mGuiEvents ));
	CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"SpeakerControlsWin/PrevSample")->subscribeEvent
	(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&GuiEvents::prevSample, mGuiEvents ));
	
*/	// setup special windows and Sliders



	mLightmap1 = static_cast<CEGUI::Scrollbar*>(CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"Lightmap1"));
	mLightmap1->setScrollPosition(0.5);
	mLightmap2 = static_cast<CEGUI::Scrollbar*>(CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"Lightmap2"));
	mLightmap2->setScrollPosition(0.1);
	mLightmap3 =  static_cast<CEGUI::Scrollbar*>(CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"Lightmap3"));
	mLightmap3->setScrollPosition(.9);
	
	mEnableGui   = static_cast<CEGUI::RadioButton*>(CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"Enable"));
		
	mFadeMesh =  static_cast<CEGUI::Scrollbar*>(CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"Fade3D"));
	mFadeMesh->setScrollPosition(.6);
	mValues = CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"Info9");

}

void Gui::show(bool toggle)
{
   if (toggle)
   {	mEditorGuiSheet->show(); }
   else
   {   mEditorGuiSheet->hide(); }
}
